package org.goodsl.mdd;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created with IntelliJ IDEA.
 * User: Simon Xiao
 * Date: 12-11-14
 * Time: 上午10:14
 * To change this template use File | Settings | File Templates.
 */
public class ValidResult implements  Iterable<SingleValidResult<?>> {

    private boolean isValid = true;
    public boolean getIsValid(){
        return isValid;
    }


    private int failCount = 0;
    private int passCount = 0;

    public int getTotalCount(){
        return results.size();
    }

    public int getFailCount(){
        return failCount;
    }
    public int getPassCount(){
        return passCount;
    }

    ArrayList<SingleValidResult<?>> results = new ArrayList<SingleValidResult<?>>(3);

    protected void addSingleResult(SingleValidResult<?> singleResult){
        if(singleResult == null) return;
        results.add(singleResult);
        isValid = isValid && singleResult.getIsValid();
        if(singleResult.getIsValid())
            passCount++;
        else
            failCount++;

    }

    protected void appendResult(ValidResult otherResult){
        appendResult(otherResult,null);
    }

    protected void appendResult(ValidResult otherResult,String preMessage){
        Iterator<SingleValidResult<?>> iterator = otherResult.iterator();
        while (iterator.hasNext()){
            SingleValidResult<?> singleResult =iterator.next();
            if(preMessage!=null)
                    singleResult.setPreMessage(preMessage);
            addSingleResult(singleResult);
        }
    }


    public Iterator<SingleValidResult<?>> iterator(){
        return results.iterator();
    }

    public Iterator<String> messages(){

        return  new Itr();
    }

    protected void clear(){
        results.clear();
        isValid = true;
        failCount = 0;
        passCount = 0;
    }

    private class Itr implements Iterator<String> {

        /**
       	 * Index of element to be returned by subsequent call to next.
       	 */
       	int cursor = 0;

        /**
         * Returns <tt>true</tt> if the iteration has more elements. (In other
         * words, returns <tt>true</tt> if <tt>next</tt> would return an element
         * rather than throwing an exception.)
         *
         * @return <tt>true</tt> if the iterator has more elements.
         */
        public boolean hasNext() {
            while (cursor<results.size()){
                if(!results.get(cursor).getIsValid())
                    return true;
                cursor++;
            }

            return false;
        }

        /**
         * Returns the next element in the iteration.
         *
         * @return the next element in the iteration.
         * @throws java.util.NoSuchElementException
         *          iteration has no more elements.
         */
        public String next() {
            while (cursor<results.size()){
                SingleValidResult<?> singleResult = results.get(cursor);
                if(!singleResult.getIsValid()){
                    cursor++;
                    return singleResult.getMessage();
                }
                cursor++;
            }
            return null;

        }

        /**
         * Removes from the underlying collection the last element returned by the
         * iterator (optional operation).  This method can be called only once per
         * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
         * the underlying collection is modified while the iteration is in
         * progress in any way other than by calling this method.
         *
         * @throws UnsupportedOperationException if the <tt>remove</tt>
         *                                       operation is not supported by this Iterator.
         * @throws IllegalStateException         if the <tt>next</tt> method has not
         *                                       yet been called, or the <tt>remove</tt> method has already
         *                                       been called after the last call to the <tt>next</tt>
         *                                       method.
         */
        public void remove() {

        }
    }



}
